package com.hzncc.flowable_diboot.service.processtransaction.impl;

import cn.hutool.core.convert.Convert;
import com.diboot.core.vo.Pagination;
import com.diboot.iam.service.IamUserService;
import com.diboot.iam.util.IamSecurityUtils;
import com.hzncc.flowable_diboot.dto.processtransaction.ProcessHistoryDTO;
import com.hzncc.flowable_diboot.util.DateUtils;
import com.hzncc.flowable_diboot.vo.processtransaction.ProcessHistoryDetailVO;
import com.hzncc.flowable_diboot.vo.processtransaction.ProcessHistoryListVO;
import com.hzncc.flowable_diboot.vo.processtransaction.ProcessTaskDetailVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springframework.stereotype.Service;

import com.diboot.core.util.S;
import com.diboot.core.service.impl.BaseServiceImpl;

import com.hzncc.flowable_diboot.entity.processtransaction.ProcessHistory;

import com.hzncc.flowable_diboot.mapper.processtransaction.ProcessHistoryMapper;
import com.hzncc.flowable_diboot.service.processtransaction.ProcessHistoryService;

import java.util.ArrayList;
import java.util.List;


/**
 * 我的已办 相关Service实现类
 *
 * @author MyName
 * @version 1.0
 * @date 2024-11-04
 * Copyright © MyCorp
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProcessHistoryServiceImpl extends BaseServiceImpl<ProcessHistoryMapper, ProcessHistory> implements ProcessHistoryService {

    private final HistoryService historyService;

    private final RuntimeService runtimeService;

    private final IamUserService iamUserService;

    @Override
    public List<ProcessHistoryListVO> getList(ProcessHistoryDTO queryDto, Pagination pagination) {
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery()
                .finished()
                .taskAssignee(IamSecurityUtils.getCurrentUserId())
                .orderByTaskCreateTime().desc();
        if (S.isNotEmpty(queryDto.getProcessedNodeName())){
            query.taskNameLike("%" + queryDto.getProcessedNodeName() + "%");
        }
        if (S.isNotEmpty(queryDto.getBusinessTitle())) {
            List<ProcessInstance> list = runtimeService.createProcessInstanceQuery()
                    .processInstanceNameLike("%" + queryDto.getBusinessTitle() + "%")
                    .list();
            if (!list.isEmpty()) {
                query.processInstanceIdIn(list.stream().map(ProcessInstance::getId).toList());
            } else {
                return new ArrayList<>();
            }
        }
        List<HistoricTaskInstance> historicTaskInstances = query.listPage((pagination.getPageIndex() - 1) * pagination.getPageSize(), pagination.getPageSize());
        List<ProcessHistoryListVO> list = new ArrayList<>();
        for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
            list.add(convert(historicTaskInstance));
        }
        return list;
    }

    private ProcessHistoryDetailVO convert(HistoricTaskInstance task) {
        List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).list();
        ProcessHistoryDetailVO processHistoryDetailVO = new ProcessHistoryDetailVO();
        if (!list.isEmpty()) {
            ProcessInstance processInstance = list.get(0);
            processHistoryDetailVO.setBusinessTitle(processInstance.getName());
            processHistoryDetailVO.setProcessDefinitionId(processInstance.getProcessDefinitionId());
            processHistoryDetailVO.setProcessInsId(processInstance.getId());
        }
        String userId = task.getAssignee();
        if (S.contains(userId, ":")) {
            userId = S.substringAfterLast(userId, ":");
        }
        processHistoryDetailVO.setProcessedNodeName(task.getName());
        processHistoryDetailVO.setNodeAgent(task.getAssignee());
        processHistoryDetailVO.setNodeAgentName(iamUserService.getEntity(userId).getRealname());
        processHistoryDetailVO.setId(task.getId());
        processHistoryDetailVO.setStartTime(DateUtils.of(task.getCreateTime()));
        processHistoryDetailVO.setType(task.getCategory());
        processHistoryDetailVO.setTaskDefinitionKey(task.getTaskDefinitionKey());
        processHistoryDetailVO.setPriority((long) task.getPriority());
        processHistoryDetailVO.setFinishTime(DateUtils.of(task.getEndTime()));
        processHistoryDetailVO.setElapsedTime(Convert.toLong(task.getDurationInMillis()));
        return processHistoryDetailVO;
    }

    @Override
    public ProcessHistoryDetailVO getDetailVO(String id) {
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().taskId(id).list();
        if (!list.isEmpty()){
            return convert(list.get(0));
        }
        return null;
    }
}